package com.irdstudio.tdp.console.api.rest;

import java.text.SimpleDateFormat;
import java.util.List;

import com.irdstudio.tdp.console.dao.domain.BatInstBatch;
import com.irdstudio.tdp.console.service.facade.BatBatchInfoConfigService;
import com.irdstudio.tdp.console.service.facade.BatBatchStageConfigService;
import com.irdstudio.tdp.console.service.facade.BatInstBatchService;
import com.irdstudio.tdp.console.service.facade.PaasAppsInfoService;
import com.irdstudio.tdp.console.service.facade.SAgentInfoService;
import com.irdstudio.tdp.console.service.facade.SSubsInfoService;
import com.irdstudio.tdp.console.service.vo.BatBatchInfoConfigVO;
import com.irdstudio.tdp.console.service.vo.BatBatchStageConfigVO;
import com.irdstudio.tdp.console.service.vo.BatInstBatchVO;
import com.irdstudio.tdp.console.service.vo.PaasAppsInfoVO;
import com.irdstudio.tdp.console.service.vo.SAgentInfoVO;
import com.irdstudio.tdp.console.service.vo.SSrvsCronConfVO;
import com.irdstudio.tdp.console.service.vo.SSubsInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.irdstudio.sdk.beans.core.enums.DateFormatConstant;
import com.irdstudio.sdk.beans.core.util.PropertiesUtil;
import com.irdstudio.sdk.beans.core.util.TimeUtil;
import com.irdstudio.sdk.beans.core.vo.ResponseData;
import com.irdstudio.sdk.ssm.util.AgentApiUtil;
import com.irdstudio.sdk.ssm.util.StringUtil;
import com.irdstudio.sdk.ssm.vo.ResponseVO;
import com.irdstudio.sdk.ssm.web.AbstractController;
import com.irdstudio.tdp.console.service.facade.SSrvsCronConfService;

@RestController
@RequestMapping("/api")
public class BatBatchInfoConfigController extends AbstractController  {
	
	@Autowired
	@Qualifier("batchConfigService")
	private BatBatchInfoConfigService batBatchInfoConfigService;
	
	@Autowired
	@Qualifier("sSrvsCronConfService")
	private SSrvsCronConfService sSrvsCronConfService;
	
	@Autowired
	@Qualifier("sAgentInfoService")
	private SAgentInfoService sAgentInfoService;

	@Autowired
	@Qualifier("stageConfigService")
	private BatBatchStageConfigService batBatchStageConfigService;


	@Autowired
	@Qualifier("instBatchService")
	private BatInstBatchService batInstBatchService;

	@Autowired
	@Qualifier("sSubsInfoService")
	private SSubsInfoService sSubsInfoService;

	@Autowired
	@Qualifier("paasAppsInfoServiceImpl")
	private PaasAppsInfoService paasAppsInfoService;


	/**
	 * 列表数据查询
	 * @param
	 * @param
	 * @return
	 */
	@RequestMapping(value="/bat/batch/info/configs", method=RequestMethod.POST)
	public @ResponseBody ResponseData<List<BatBatchInfoConfigVO>> queryBatBatchInfoConfigAll(
			BatBatchInfoConfigVO vo) {		
		List<BatBatchInfoConfigVO> outputVo = batBatchInfoConfigService.queryAllOwner(vo);
		return getResponseData(outputVo);
		
	}
	
	/**
	 * 根据主键查询详情
	 * @return
	 */
	@RequestMapping(value="/bat/batch/info/config/{batchId}", method=RequestMethod.GET)
	public @ResponseBody ResponseData<BatBatchInfoConfigVO> queryByPk(@PathVariable("batchId") String batchId) {		
		BatBatchInfoConfigVO inVo = new BatBatchInfoConfigVO();
				inVo.setBatchId(batchId);
		BatBatchInfoConfigVO outputVo = batBatchInfoConfigService.queryByPk(inVo);
		return getResponseData(outputVo);
		
	}
	
	/**
	 * 根据主键删除信息
	 * @param
	 * @return
	 */
	@RequestMapping(value="/bat/batch/info/config", method=RequestMethod.DELETE)
	public @ResponseBody ResponseData<Integer> deleteByPk(@RequestBody BatBatchInfoConfigVO inBatBatchInfoConfigVo) {		
		int outputVo = batBatchInfoConfigService.deleteByPk(inBatBatchInfoConfigVo);
		
		//若刪除批次成功，则在定时调度配置表中刪除一条数据
		if(outputVo == 1) {
			SSrvsCronConfVO paramVO = new SSrvsCronConfVO();
			paramVO.setJobCode(inBatBatchInfoConfigVo.getBatchId());
			sSrvsCronConfService.deleteByPk(paramVO);
		}
		
		return getResponseData(outputVo);
	}
	
	/**
	 * 根据主键更新信息
	 * @param inBatBatchInfoConfigVo
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/bat/batch/info/config", method=RequestMethod.PUT)
	public @ResponseBody ResponseData<Integer> updateByPk(@RequestBody BatBatchInfoConfigVO inBatBatchInfoConfigVo) throws Exception {		
		int outputVo = batBatchInfoConfigService.updateByPk(inBatBatchInfoConfigVo);
		
		if(outputVo == 1) {
			//不管发起前的发起方式是否“定时调度”，都在修改成功后先删除定时调度配置信息，然后在判断，若修改后
			//的发起方式是“定时调度”，则新增一条记录，若不是，则不再信息
			//定时作业编号
			SSrvsCronConfVO paramVO = new SSrvsCronConfVO();
			paramVO.setJobCode(inBatBatchInfoConfigVo.getBatchId());
			//先查询是否已经存在
			SSrvsCronConfVO confVO = sSrvsCronConfService.queryByPk(paramVO);
			
			int count = 1;
			//若存在，则先删除
			if(confVO != null) {
				count = sSrvsCronConfService.deleteByPk(paramVO);
				
				if(count != 1){
					ResponseData<Integer> data = getResponseData(count);
					data.setMessage("删除定时调度配置数据失败！操作影响了"+count+"条记录");
					return data;
				}
			}
			
			//若修改批次成功，且修改后发起方式为“定时调度”，则在定时调度配置表中新增一条数据
			if(count == 1 && inBatBatchInfoConfigVo.getLaunchType() != null && "1".equals(inBatBatchInfoConfigVo.getLaunchType())){
				//若删除成功，则再新增一条定时调度配置信息
				SSrvsCronConfVO addConfVO = new SSrvsCronConfVO();
				addConfVO.setJobCode(inBatBatchInfoConfigVo.getBatchId());
				addConfVO.setJobDesc(inBatBatchInfoConfigVo.getBatchName());
				addConfVO.setCronExpression(inBatBatchInfoConfigVo.getBatchCronValue());
				addConfVO.setAgentId(inBatBatchInfoConfigVo.getAgentId());
				addConfVO.setSubsCode(inBatBatchInfoConfigVo.getSubsCode());
				addConfVO.setJobState("S");
				addConfVO.setJobClass("com.irdstudio.bsp.executor.rest.job.BatchStarter");
				addConfVO.setJobClassType("local");
				addConfVO.setJobMethod("doExcetue");
				addConfVO.setAgainTime(3);
				addConfVO.setRetrySecond(60);
				
				if(confVO != null) {
					addConfVO.setJobClassType(confVO.getJobClassType());
					addConfVO.setJobClass(confVO.getJobClass());
					addConfVO.setJobMethod(confVO.getJobMethod());
					addConfVO.setJobDesc(confVO.getJobDesc());
				}
				
				sSrvsCronConfService.insertSSrvsCronConf(addConfVO);
			}
		}
		
		return getResponseData(outputVo);
		
	}
	
	/**
	 * 新增数据
	 * @param inBatBatchInfoConfigVo
	 * @return
	 */
	@RequestMapping(value="/bat/batch/info/config", method=RequestMethod.POST)
	public @ResponseBody ResponseData<Integer> insertBatBatchInfoConfig(@RequestBody BatBatchInfoConfigVO inBatBatchInfoConfigVo) {
		int outputVo = batBatchInfoConfigService.insertBatBatchInfoConfig(inBatBatchInfoConfigVo);
		
		//若新增批次成功，增加默认批次阶段
		if(outputVo == 1){
			//默认新增五个批次阶段
			BatBatchStageConfigVO batBatchStageConfigVO=new BatBatchStageConfigVO();
			batBatchStageConfigVO.setBatchId(inBatBatchInfoConfigVo.getBatchId());
			batBatchStageConfigVO.setStageId("01");
			batBatchStageConfigVO.setStageName("批次开始");
			batBatchStageConfigVO.setRemark("批次开始");
			batBatchStageConfigService.insertBatBatchStageConfig(batBatchStageConfigVO);
			batBatchStageConfigVO.setStageId("02");
			batBatchStageConfigVO.setStageName("数据装载");
			batBatchStageConfigVO.setRemark("数据装载");
			batBatchStageConfigService.insertBatBatchStageConfig(batBatchStageConfigVO);
			batBatchStageConfigVO.setStageId("03");
			batBatchStageConfigVO.setStageName("数据卸载");
			batBatchStageConfigVO.setRemark("数据卸载");
			batBatchStageConfigService.insertBatBatchStageConfig(batBatchStageConfigVO);
			batBatchStageConfigVO.setStageId("04");
			batBatchStageConfigVO.setStageName("业务处理");
			batBatchStageConfigVO.setRemark("业务处理");
			batBatchStageConfigService.insertBatBatchStageConfig(batBatchStageConfigVO);
			batBatchStageConfigVO.setStageId("05");
			batBatchStageConfigVO.setStageName("批次结束");
			batBatchStageConfigVO.setRemark("批次结束");
			batBatchStageConfigService.insertBatBatchStageConfig(batBatchStageConfigVO);
			//发起方式为“定时调度”，则在定时调度配置表中新增一条数据，
			if(inBatBatchInfoConfigVo.getLaunchType() != null && "1".equals(inBatBatchInfoConfigVo.getLaunchType())){
				SSrvsCronConfVO addConfVO = new SSrvsCronConfVO();
				addConfVO.setJobCode(inBatBatchInfoConfigVo.getBatchId());
				addConfVO.setJobDesc(inBatBatchInfoConfigVo.getBatchName());
				addConfVO.setCronExpression(inBatBatchInfoConfigVo.getBatchCronValue());
				addConfVO.setAgentId(inBatBatchInfoConfigVo.getAgentId());
				addConfVO.setSubsCode(inBatBatchInfoConfigVo.getSubsCode());
				addConfVO.setJobState("S");
				addConfVO.setJobClass("com.irdstudio.bsp.executor.rest.job.BatchStarter");
				addConfVO.setJobClassType("local");
				addConfVO.setJobMethod("doExcetue");
				addConfVO.setAgainTime(3);
				addConfVO.setRetrySecond(60);
				sSrvsCronConfService.insertSSrvsCronConf(addConfVO);
			}
		}
		return getResponseData(outputVo);
	}
	
	/**
	 * 批次执行操作
	 * 
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/bat/batch/info/action/", method = RequestMethod.GET)
	public @ResponseBody ResponseData<Boolean> startBatch(@RequestParam("batchSerialNo") String batchSerialNo, @RequestParam("batchId") String batchId, @RequestParam("batchAction") String batchAction) {
		//批次查询
		BatBatchInfoConfigVO params = new BatBatchInfoConfigVO();
		params.setBatchId(batchId);
		BatBatchInfoConfigVO batchConf = batBatchInfoConfigService.queryByPk(params);
		
		//查询agent配置
		SAgentInfoVO inVo = new SAgentInfoVO();
		inVo.setAgentId(batchConf.getAgentId());
		SAgentInfoVO agentInfo = sAgentInfoService.queryByPk(inVo);
		
		//执行远程API调用
		ResponseData<Boolean> data = null;
		if (agentInfo != null && StringUtil.isNotEmpty(agentInfo.getAgentUrl())) {
			
			try {
			    //使用时间戳 在这里不需要生成序号 由批次引擎生成
			    // if("none".equals(batchSerialNo)) {
			    //     batchSerialNo = TimeUtil.getTimeStampByPattern(DateFormatConstant.DATETIME_SSS_FORMAT_COMPACT);
			    // }
				ResponseVO response = AgentApiUtil.actionBatch(agentInfo.getAgentUrl(),  null, batchId, batchAction);
				if (response != null && StringUtil.isNotEmpty(response.getFlag())
						&& ResponseVO.SUCCESS.equals(response.getFlag())) {
					
					data = getResponseData(true);
					if (response != null && StringUtil.isNotEmpty(response.getMsg())) {
						data.setMessage(response.getMsg());
						logger.info(response.getMsg());
					} else {
						data.setMessage("批次执行成功！");
						logger.info("批次执行成功！agentId:" + agentInfo.getAgentId() + ", agent地址：" + agentInfo.getAgentUrl()
								+ ", 批次号：" + batchId + ", 批次动作：" + batchAction + "，批次流水号：" + batchSerialNo);
					}
				} else {
					data = getResponseData(false);
					if (response != null && StringUtil.isNotEmpty(response.getMsg())) {
						data.setMessage(response.getMsg());
						logger.info(response.getMsg());
					} else {
						data.setMessage("批次执行失败！");
						logger.info("批次执行失败！");
					}
				}

			} catch (Exception e) {
				logger.error("无法调用远程地址：" + agentInfo.getAgentUrl(), e);

				data = getResponseData(false);
				data.setMessage("无法调用远程地址：" + agentInfo.getAgentUrl());
			}

		} else {
			logger.error("没有找到配置信息");
			data = getResponseData(false);
			data.setMessage("没有找到配置信息！");
		}
			
		return data;
	}
	
	/**
     * 业务流转批次执行操作
     * 
     * @param
     * @return
     */
    @RequestMapping(value = "/bat/bpm/batch/info/action/", method = RequestMethod.GET)
    public @ResponseBody ResponseData<Boolean> startBpmBatch(@RequestParam("batchSerialNo") String batchSerialNo, 
            @RequestParam("batchId") String batchId, @RequestParam("batchAction") String batchAction) {
        String agentUrl = PropertiesUtil.getPropertyByKey("application", "bpm.agent.url");
        
        //执行远程API调用
        ResponseData<Boolean> data = null;
        try {
            ResponseVO response = AgentApiUtil.actionBpmBatch(agentUrl, batchId, batchSerialNo, batchAction);
            if (response != null && StringUtil.isNotEmpty(response.getFlag())
                    && ResponseVO.SUCCESS.equals(response.getFlag())) {
                
                data = getResponseData(true);
                if (response != null && StringUtil.isNotEmpty(response.getMsg())) {
                    data.setMessage(response.getMsg());
                    logger.info(response.getMsg());
                } else {
                    data.setMessage("业务流转批次执行成功！");
                    logger.info(batchSerialNo+"批次执行成功！agent地址：" + agentUrl + ", 批次号：" + batchId + ", 批次流水号："+batchSerialNo+", 批次动作：" + batchAction);
                }
            } else {
                data = getResponseData(false);
                if (response != null && StringUtil.isNotEmpty(response.getMsg())) {
                    data.setMessage(response.getMsg());
                    logger.info(response.getMsg());
                } else {
                    data.setMessage("批次执行失败！");
                    logger.info("批次执行失败！");
                }
            }
        } catch (Exception e) {
            logger.error("无法调用远程地址：" + agentUrl, e);

            data = getResponseData(false);
            data.setMessage("无法调用远程地址：" + agentUrl);
        }
            
        return data;
    }

	/**
	 * 批次执行操作
	 *
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/bat/batch/info/action/gencode/", method = RequestMethod.GET)
	public @ResponseBody ResponseData<String> startGencodeBatch(
						@RequestParam("appId") String appId,
						@RequestParam("batchSerialNo") String batchSerialNo,
						@RequestParam("batchId") String batchId,
						@RequestParam("batchAction") String batchAction) {
		//批次查询
		BatBatchInfoConfigVO params = new BatBatchInfoConfigVO();
		params.setBatchId(batchId);
		BatBatchInfoConfigVO batchConf = batBatchInfoConfigService.queryByPk(params);

		//查询agent配置
		SAgentInfoVO inVo = new SAgentInfoVO();
		inVo.setAgentId(batchConf.getAgentId());
		SAgentInfoVO agentInfo = sAgentInfoService.queryByPk(inVo);

		SSubsInfoVO subsInfoParam = new SSubsInfoVO();
		subsInfoParam.setSubsCode(batchConf.getSubsCode());
		SSubsInfoVO sSubsInfo = sSubsInfoService.queryByPk(subsInfoParam);
		//执行远程API调用
		ResponseData<String> data = null;
		if (agentInfo != null && StringUtil.isNotEmpty(agentInfo.getAgentUrl())) {

			try {
				//使用时间戳
				if("none".equals(batchSerialNo)) {
					batchSerialNo = TimeUtil.getTimeStampByPattern(DateFormatConstant.DATETIME_SSS_FORMAT_COMPACT);
				}
				// 检查状态 如果不是9 重置为9
				BatInstBatchVO batInstParams = new BatInstBatchVO();
				batInstParams.setBatchId(batchId);
				List<BatInstBatchVO> batInsts = batInstBatchService.queryAllOwner(batInstParams);
				if (batInsts != null && !batInsts.isEmpty()) {
					BatInstBatchVO batInst = batInsts.get(0);
					boolean needUpdate = false;
					if (!batInst.getBatchState().equals("9")) {
						batInst.setBatchState("9");
						needUpdate = true;
					}

					SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd");
					// 2.2 子系统批次完成日期
					String subsBatDate = sSubsInfo.getSubsBatDate();
					if (StringUtils.isBlank(subsBatDate)) {
						throw new Exception("获取子系统批次完成日期为空！");
					}
					// 2.3 批次实例表中的批次日期
					String batchDate = batInst.getBatchDate();
					if (StringUtils.isBlank(batchDate)) {
						batInst.setBatchDate(subsBatDate);
						needUpdate = true;
					}
					// 2.4比较:若子系统批次完成日期小于批次实例表中批次日期，则说明错误，抛出“上一日期的批次尚未运行成功！”
					if (format.parse(subsBatDate).before(format.parse(batchDate))) {
						if (!"M".equals(batchConf.getIsRunAgain())) {
							batInst.setBatchDate(subsBatDate);
							needUpdate = true;
						}
					}

					// 2.5若子系统批次完成日期大于批次实例表中的批次日期，则错误，提示“上次批次完成日期异常，请检查！”
					if (format.parse(subsBatDate).after(format.parse(batchDate))) {
						batInst.setBatchDate(subsBatDate);
						needUpdate = true;
					}

					if (needUpdate) {
						batInstBatchService.updateByPk(batInst);
					}
				}
				// 将批次序号保存到 Paas_apps_info 中
				PaasAppsInfoVO appsParam = new PaasAppsInfoVO();
				appsParam.setAppId(appId);
				PaasAppsInfoVO appInfo = paasAppsInfoService.queryByPk(appsParam);
				if (appInfo != null) {
					appInfo.setBatchSerialNo(batchSerialNo);
					paasAppsInfoService.updateByPk(appInfo);
				}
				ResponseVO response = AgentApiUtil.actionBatch(agentInfo.getAgentUrl(), batchSerialNo, batchId, batchAction);
				if (response != null && StringUtil.isNotEmpty(response.getFlag())
						&& ResponseVO.SUCCESS.equals(response.getFlag())) {

					data = getResponseData(batchSerialNo);
					if (response != null && StringUtil.isNotEmpty(response.getMsg())) {
						data.setMessage(response.getMsg());
						logger.info(response.getMsg());
					} else {
						data.setMessage("批次执行成功！");
						logger.info("批次执行成功！agentId:" + agentInfo.getAgentId() + ", agent地址：" + agentInfo.getAgentUrl()
								+ ", 批次号：" + batchId + ", 批次动作：" + batchAction + "，批次流水号：" + batchSerialNo);
					}
				} else {
					data = getResponseData(null);
					if (response != null && StringUtil.isNotEmpty(response.getMsg())) {
						data.setMessage(response.getMsg());
						logger.info(response.getMsg());
					} else {
						data.setMessage("批次执行失败！");
						logger.info("批次执行失败！");
					}
				}

			} catch (Exception e) {
				logger.error("无法调用远程地址：" + agentInfo.getAgentUrl(), e);

				data = getResponseData(null);
				data.setMessage("无法调用远程地址：" + agentInfo.getAgentUrl());
			}

		} else {
			logger.error("没有找到配置信息");
			data = getResponseData(null);
			data.setMessage("没有找到配置信息！");
		}

		return data;
	}
}
